/*           Copyright(c) 2005-2008 Dave Sexton            *
 *                   HtmlEditor Control                    *
 * http://www.codeplex.com/DocProject/Project/License.aspx *
 ***********************************************************/
using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel.Design;
using System.ComponentModel;
using System.Windows.Forms;

namespace DaveSexton.Controls.Design
{
	/// <summary>
	/// Displays a drop-down list of controls that can be selected as the value of a property in the property grid being hosted by a designer, 
	/// much like the editor used for the <see cref="System.Windows.Forms.Form.AcceptButton" /> property of the 
	/// <see cref="System.Windows.Forms.Form" /> class.
	/// </summary>
	internal abstract class ControlSelectorEditor : ObjectSelectorEditor
	{
		#region Private / Protected
		private readonly Type baseType;
		#endregion

		#region Constructors
		/// <summary>
		/// Constructs a new instance of the <see cref="ControlSelectorEditor" /> class.
		/// </summary>
		/// <param name="baseType"><see cref="Type" /> used as the base <see cref="Type" /> for
		/// all components in the drop-down list that are hosted in the designer of the object for which the editor is displayed.</param>
		public ControlSelectorEditor(Type baseType)
		{
			if (baseType == null)
				throw new ArgumentNullException("baseType");

			this.baseType = baseType;
		}
		#endregion

		#region Methods
		protected override void FillTreeWithData(Selector selector, System.ComponentModel.ITypeDescriptorContext context, IServiceProvider provider)
		{
			selector.Clear();
			selector.AddNode("(none)", null, null);

			IReferenceService referenceService = provider.GetService(typeof(IReferenceService)) as IReferenceService;

			foreach (object value in context.Container.Components)
			{
				if (baseType.IsAssignableFrom(value.GetType()))
				{
					string name = null;

					IComponent component = value as IComponent;

					if (component != null && component.Site != null)
						name = component.Site.Name;
					else if (referenceService != null)
						name = referenceService.GetName(value);
					else
						throw new InvalidOperationException(DaveSexton.Controls.Resources.Errors.ControlSelectorEditorNoNameService);

					selector.AddNode(name, value, null);
				}
			}
		}
		#endregion
	}
}
